//**********************************************************************
//	Programmer	-	Sujal Bista
//	File Name	-	graphicsUtility.cpp
//	Description	:	
//					Graphics Utility
//**********************************************************************
#include "graphicsUtility.h"
#include "utilityFunctions.h"
#include "bucketList.h"

#ifdef _MSC_VER
	#ifdef _DEBUG
		#include <crtdbg.h>
		#include <stdlib.h>
		#define DEBUG_NEW new(_NORMAL_BLOCK ,__FILE__, __LINE__)
		#define new DEBUG_NEW	
	#else
		#define DEBUG_NEW new
	#endif		
#endif



//default constructor
graphicsUtility::graphicsUtility(void)
{
	//allocate space for shaders
	basicVShaders=new shaderVertex[BASIC_SHADER_TYPE_END];
	basicPShaders=new shaderPixel[BASIC_SHADER_TYPE_END];
	
	//vertex layouts
	vertexLayouts=new inputLayout[BASIC_SHADER_TYPE_END];

	//shader buffers
	shaderBuffers=new buffer[BASIC_SHADER_TYPE_END];

	//font
	fonts=new font[BASIC_FONT_TYPE_END];
}

//initilizes the utility
bool graphicsUtility::init(HWND &hWnd,const unsigned int &width, const unsigned int &height)
{
	//pass parameter to the graphics library
	gl.setWindowHandler(hWnd);
	
	//init the graphics
	if(!gl.init(&gDevice,&dContext,&rTarget,&dStencil,&rTargetView,&dStencilView))
		return false;

	//if(!gl.resize(&gDevice,&dContext,&rTarget,&dStencil,&rTargetView,&dStencilView,width,height))
	//	return false;

	//filled state
	if(!gDevice.createRasterizerState(graphicsDefinitions::FILL_MODE_SOLID,graphicsDefinitions::CULL_MODE_BACK,true,0,0.0f,0.0f,true,false,false,false,&solidStateMode))
		return false;

	//wire state
	if(!gDevice.createRasterizerState(graphicsDefinitions::FILL_MODE_WIREFRAME,graphicsDefinitions::CULL_MODE_BACK,true,0,0.0f,0.0f,true,false,false,false,&wireFrameStateMode))
		return false;

	//loads up the shaders for utility
	if(!loadShaders(dContext))
		return false;

	//init fonts for utility
	if(!loadFonts(dContext))
		return false;

	//set the default rasterizer mode to fill
	//dContext.RSSetState(&solidStateMode);
	setWireFrame(false);

	return true;
}

//init fonts
bool graphicsUtility::loadFonts(deviceContext &dContext)
{
	char fileNames[][128]=
		{
			"../LibGraphics/media/ascii.ini"
		};

	for(unsigned int i=0;i<BASIC_FONT_TYPE_END;i++)
	{
		bucketList<setupData> setupContent;
		//read setup file
		if(readSetupFile(fileNames[i],setupContent))
		{
			//loads setup data
			for(unsigned int j=0;j<setupContent.size();j++)
			{
				setupData &sData=setupContent[j];

				if(strcmp(sData.name,"FileName")==0)	//check for filename
				{
					gDevice.createShaderResourceViewFromFile(sData.value,&(fonts[i].fontTextureSRV));//open the file
					//unsigned int seaFloorWidth=512,seaFloorHeight=512;
					//texture2D *dynamicTexture=new texture2D;

					////create a blank 2D texture
					//graphicsUtility::createTexture2D(seaFloorWidth,seaFloorHeight,graphicsDefinitions::DATA_FORMAT_R8G8B8A8_UNORM,*dynamicTexture);

					////create the texture data
					//unsigned int bytesPerPixel=4;
					//unsigned char *textureData=new unsigned char[seaFloorWidth*seaFloorHeight*bytesPerPixel];
					//for(unsigned int y=0;y<seaFloorHeight;y++)
					//{
					//	for(unsigned int x=0;x<seaFloorWidth;x++)
					//	{
					//		unsigned int pixelPos=y*seaFloorWidth+x;
					//		if(x==y)
					//		{
					//			textureData[pixelPos*bytesPerPixel]=255;
					//			textureData[pixelPos*bytesPerPixel+3]=255;
					//		}
					//		else
					//		{
					//			textureData[pixelPos*bytesPerPixel]=0;
					//			textureData[pixelPos*bytesPerPixel+3]=0;
					//		}
					//		textureData[pixelPos*bytesPerPixel+1]=0;
					//		textureData[pixelPos*bytesPerPixel+2]=0;
					//		
					//	}
					//}

					////update the texture resource
					//graphicsUtility::updateTexture2D(dContext,*dynamicTexture,0,0,seaFloorWidth,seaFloorHeight,textureData,seaFloorWidth*bytesPerPixel,seaFloorWidth*seaFloorHeight*bytesPerPixel);

					//delete[] textureData;

					//fonts[i].fontTextureSRV.clear();
					////this program saves memory stuff for opengl. Need a duplicate it
					//gDevice.createShaderResourceView(dynamicTexture,graphicsDefinitions::DATA_FORMAT_R8G8B8A8_UNORM,graphicsDefinitions::SRV_DIMENSION_TEXTURE2D,0,(unsigned int)-1,0,0,&fonts[i].fontTextureSRV);

				}
				else if(strcmp(sData.name,"ImageWidth")==0)	//check for CharWidth
					sscanf(sData.value,"%d",&fonts[i].imageWidth);
				else if(strcmp(sData.name,"ImageHeight")==0)//check for CharHeight
					sscanf(sData.value,"%d",&fonts[i].imageHeight);
				else if(strcmp(sData.name,"CharWidth")==0)	//check for CharWidth
					sscanf(sData.value,"%d",&fonts[i].characterWidth);
				else if(strcmp(sData.name,"CharHeight")==0)//check for CharHeight
					sscanf(sData.value,"%d",&fonts[i].characterHeight);
				else if(strcmp(sData.name,"Color")==0)	//check for Color
					sscanf(sData.value,"%f %f %f %f",&fonts[i].color.r,&fonts[i].color.g,&fonts[i].color.b,&fonts[i].color.a);
				else if(strcmp(sData.name,"Char Info")==0)	//check for TranslateX
				{
					int charNumber=0,tempI;
					//scan the character Number
					sscanf(sData.value,"%i",&charNumber);
					//fill in the character info data
					sscanf(sData.value,"%i,%i,%i,%i,%i,%i",&tempI,&fonts[i].charDetails[charNumber].startX,&fonts[i].charDetails[charNumber].startY,&fonts[i].charDetails[charNumber].width,&fonts[i].charDetails[charNumber].height,&fonts[i].charDetails[charNumber].translateAmount);
				}

			}

			//make font
			//buildFont();
		}

		graphicsDefinitions::TEXTURE_ADDRESS_MODE addMode[3]={
			graphicsDefinitions::TEXTURE_ADDRESS_MODE_WRAP,
			graphicsDefinitions::TEXTURE_ADDRESS_MODE_WRAP,
			graphicsDefinitions::TEXTURE_ADDRESS_MODE_WRAP
		};
		float borderColor[4]={0,0,0,0};
		gDevice.createSamplerState(
				graphicsDefinitions::FILTER_MIN_MAG_MIP_LINEAR,
				addMode,
				0,
				0,
				graphicsDefinitions::COMPARISON_FUNC_NEVER,
				borderColor,
				0,
				10000,
				&fonts[i].fontTextureSampler
			);
		fonts[i].charPerRow=16;
		fonts[i].charPerCol=16;
	}

	return true;
}

//loads up the shaders
bool graphicsUtility::loadShaders(deviceContext &dContext)
{
	char shaderFileNames[][128]=
		{
			#ifdef _USE_DIRECTX_
				"../LibGraphics/Shaders/basicColorShader.fx",
				"../LibGraphics/Shaders/basicColorNormalShader.fx",
				"../LibGraphics/Shaders/basicColorTextureShader.fx",
				"../LibGraphics/Shaders/basicColorNormalTextureShader.fx",
				"../LibGraphics/Shaders/basicColorTexture2DShader.fx",
			#endif
			#ifdef _USE_OPENGL_
				"../LibGraphics/Shaders/basicColorShader.glfx",
				"../LibGraphics/Shaders/basicColorNormalShader.glfx",
				"../LibGraphics/Shaders/basicColorTextureShader.glfx",
				"../LibGraphics/Shaders/basicColorNormalTextureShader.glfx",
				"../LibGraphics/Shaders/basicColorTexture2DShader.glfx",
			#endif

		};

	//remove all the shader attachments
	dContext.VSSetShader(NULL, NULL, 0 );
	dContext.HSSetShader(NULL, NULL, 0 );
	dContext.DSSetShader(NULL, NULL, 0 );
	dContext.GSSetShader(NULL, NULL, 0 );
	dContext.PSSetShader(NULL, NULL, 0 );

	//load up the shader
	for(unsigned int i=0;i<BASIC_SHADER_TYPE_END;i++)
	{
		char *shaderFileName=shaderFileNames[i];

		//vertex shader data
		blob *vShaderData=new blob;
		if(!gl.compileShaderFromFile(shaderFileName, "VS", "vs_5_0",vShaderData))
		{
			delete vShaderData;
			return false;		
		}
	
		//create vertex shader
		if(!gDevice.createVertexShader(vShaderData,&basicVShaders[i]))
		{
			delete vShaderData;
			return false;
		}

		//pixel shader data
		blob *pShaderData=new blob;
		if(!gl.compileShaderFromFile(shaderFileName, "PS", "ps_5_0", pShaderData))
		{
			delete pShaderData;
			return false;
		}

		//create pixel shader
		if(!gDevice.createPixelShader(pShaderData,&basicPShaders[i]))
		{
			delete pShaderData;
			return false;
		}

		//attach the shaders
		dContext.VSSetShader(&basicVShaders[i], NULL, 0 );
		dContext.PSSetShader(&basicPShaders[i], NULL, 0 );

		graphics::bufferDesc desc;
		
		switch(i)
		{
			case BASIC_SHADER_TYPE_COLOR:
				{
					graphics::inputElementDesc inputDesc[]=
					{
						{ graphicsDefinitions::INPUT_DATA_TYPE_POSITION, 0, graphicsDefinitions::DATA_FORMAT_R32G32B32_FLOAT, 0, 0, graphicsDefinitions::INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
					};
					unsigned int inputDescCount=sizeof(inputDesc)/sizeof(graphics::inputElementDesc);
					//creates input Layout
					gDevice.createInputLayout(inputDesc,inputDescCount,vShaderData,&vertexLayouts[i]);
					
					//also add the size of buffer type
					desc.byteWidth=sizeof(shaderBufferColor);

					dContext.shaderBegin();
						basicCSVariable.shaderBufferIndex=dContext.getUniformBlockIndex("BufferDynamicPerFrame");
					dContext.shaderEnd();
				}
				break;

			case BASIC_SHADER_TYPE_COLOR_NORMAL:
				{
					graphics::inputElementDesc inputDesc[]=
					{
						{ graphicsDefinitions::INPUT_DATA_TYPE_POSITION, 0, graphicsDefinitions::DATA_FORMAT_R32G32B32_FLOAT, 0, 0, graphicsDefinitions::INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
						{ graphicsDefinitions::INPUT_DATA_TYPE_NORMAL, 0, graphicsDefinitions::DATA_FORMAT_R32G32B32_FLOAT, 0, 12, graphicsDefinitions::INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
					};
					unsigned int inputDescCount=sizeof(inputDesc)/sizeof(graphics::inputElementDesc);
					//creates input Layout
					gDevice.createInputLayout(inputDesc,inputDescCount,vShaderData,&vertexLayouts[i]);

					//also add the size of buffer type
					desc.byteWidth=sizeof(shaderBufferColorNormal);

					dContext.shaderBegin();
						basicCNSVariable.shaderBufferIndex=dContext.getUniformBlockIndex("BufferDynamicPerFrame");
					dContext.shaderEnd();
				}
				break;

			case BASIC_SHADER_TYPE_COLOR_TEXTURE:
				{
					graphics::inputElementDesc inputDesc[]=
					{
						{ graphicsDefinitions::INPUT_DATA_TYPE_POSITION, 0, graphicsDefinitions::DATA_FORMAT_R32G32B32_FLOAT, 0, 0, graphicsDefinitions::INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
						{ graphicsDefinitions::INPUT_DATA_TYPE_TEXCOORD, 0, graphicsDefinitions::DATA_FORMAT_R32G32_FLOAT, 0, 12, graphicsDefinitions::INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
					};
					unsigned int inputDescCount=sizeof(inputDesc)/sizeof(graphics::inputElementDesc);
					//creates input Layout
					gDevice.createInputLayout(inputDesc,inputDescCount,vShaderData,&vertexLayouts[i]);

					//also add the size of buffer type
					desc.byteWidth=sizeof(shaderBufferColor);

					dContext.shaderBegin();
						basicCTSVariable.shaderBufferIndex=dContext.getUniformBlockIndex("BufferDynamicPerFrame");
						basicCTSVariable.textureIndex=dContext.getUniformLocation("textureDiffuse");
					dContext.shaderEnd();
				}
				break;

			case BASIC_SHADER_TYPE_COLOR_NORMAL_TEXTURE:
				{
					graphics::inputElementDesc inputDesc[]=
					{
						{ graphicsDefinitions::INPUT_DATA_TYPE_POSITION, 0, graphicsDefinitions::DATA_FORMAT_R32G32B32_FLOAT, 0, 0, graphicsDefinitions::INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
						{ graphicsDefinitions::INPUT_DATA_TYPE_NORMAL, 0, graphicsDefinitions::DATA_FORMAT_R32G32B32_FLOAT, 0, 12, graphicsDefinitions::INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
						{ graphicsDefinitions::INPUT_DATA_TYPE_TEXCOORD, 0, graphicsDefinitions::DATA_FORMAT_R32G32_FLOAT, 0, 24, graphicsDefinitions::INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
					};
					unsigned int inputDescCount=sizeof(inputDesc)/sizeof(graphics::inputElementDesc);
					//creates input Layout
					gDevice.createInputLayout(inputDesc,inputDescCount,vShaderData,&vertexLayouts[i]);

					//also add the size of buffer type
					desc.byteWidth=sizeof(shaderBufferColorNormal);

					dContext.shaderBegin();
						basicCNTSVariable.shaderBufferIndex=dContext.getUniformBlockIndex("BufferDynamicPerFrame");
						basicCNTSVariable.textureIndex=dContext.getUniformLocation("textureDiffuse");
					dContext.shaderEnd();
				}
				break;
			case BASIC_SHADER_TYPE_TEXTURE_2D:
				{
					graphics::inputElementDesc inputDesc[]=
					{
						{ graphicsDefinitions::INPUT_DATA_TYPE_POSITION, 0, graphicsDefinitions::DATA_FORMAT_R32G32B32_FLOAT, 0, 0, graphicsDefinitions::INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
						{ graphicsDefinitions::INPUT_DATA_TYPE_TEXCOORD, 0, graphicsDefinitions::DATA_FORMAT_R32G32_FLOAT, 0, 12, graphicsDefinitions::INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
					};
					unsigned int inputDescCount=sizeof(inputDesc)/sizeof(graphics::inputElementDesc);
					//creates input Layout
					gDevice.createInputLayout(inputDesc,inputDescCount,vShaderData,&vertexLayouts[i]);

					//also add the size of buffer type
					desc.byteWidth=sizeof(shaderBufferColor);

					dContext.shaderBegin();
						basicCT2DSVariable.shaderBufferIndex=dContext.getUniformBlockIndex("BufferDynamicPerFrame");
						basicCT2DSVariable.textureIndex=dContext.getUniformLocation("textureDiffuse");
					dContext.shaderEnd();
				}
				break;
		};

		
		//buffer desc
		desc.usage=graphicsDefinitions::USAGE_DEFAULT;
		desc.bindFlags=graphicsDefinitions::BIND_FLAG_CONSTANT_BUFFER;
		desc.cpuAccessFlags=graphicsDefinitions::CPU_ACCESS_FLAG_NONE;
		desc.miscFlags=graphicsDefinitions::RESOURCE_MISC_FLAG_NONE;
		desc.structureByteStride=0;

		//create buffer in GPU
		gDevice.createBuffer(desc,NULL,0,0,&shaderBuffers[i]);

		
		delete pShaderData;
		delete vShaderData;
	}

	//remove all the shader attachments
	dContext.VSSetShader(NULL, NULL, 0 );
	dContext.HSSetShader(NULL, NULL, 0 );
	dContext.DSSetShader(NULL, NULL, 0 );
	dContext.GSSetShader(NULL, NULL, 0 );
	dContext.PSSetShader(NULL, NULL, 0 );

	return true;
}

//creates blank 2D texture
bool graphicsUtility::createTexture2D(const unsigned int &width, const unsigned int &height, const graphicsDefinitions::DATA_FORMAT &format,texture2D &text2D)
{
	//create the description
	graphics::texture2DDesc texDesc;
	texDesc.width=width;
	texDesc.height=height;
	texDesc.mipLevels=1;
	texDesc.arraySize=1;
	texDesc.format=format;
	texDesc.sampleDesc.count = 1;
	texDesc.sampleDesc.quality = 0;
	texDesc.usage = graphicsDefinitions::USAGE_DEFAULT;
	texDesc.bindFlags =graphicsDefinitions:: BIND_FLAG_SHADER_RESOURCE;
	texDesc.cpuAccessFlags = 0;
	texDesc.miscFlags = 0;

	//create 2D texture
	gDevice.createTexture2D(texDesc,0,0,0, &text2D);
	return true;
}

//updates 2D texture
bool graphicsUtility::updateTexture2D(deviceContext &dContext, texture2D &text2D, const unsigned int &startX, const unsigned int &startY, const unsigned int &width, const unsigned int &height, void *data, const unsigned int &rowSize,const unsigned int &dataSize)
{
	graphics::box updateArea;
	updateArea.left=startX;
	updateArea.right=width;
	updateArea.top=startY;
	updateArea.bottom=height;
	updateArea.front=0;
	updateArea.back=1;

	//update the resource
	dContext.updateSubResource(&text2D, NULL, &updateArea, data, rowSize, dataSize);

	return true;
}

//uses basic shader to draw
bool graphicsUtility::drawColor(deviceContext &dContext,buffer &vertexBuffer,const graphicsDefinitions::PRIMITIVE_TOPOLOGY &topology,const float4x4 &worldMatrix,const float4x4 &viewMatrix, const float4x4 &projMatrix,const float4 &color,const unsigned int &vertexCount,const unsigned int &startVertexLocation)
{

	// Update variables that change once per frame
	struct shaderBufferColor shaderData;
	shaderData.worldMatrix=worldMatrix;
	shaderData.viewMatrix=viewMatrix; 
	shaderData.projMatrix=projMatrix;
	shaderData.color=color;
	
	dContext.updateSubResource(&shaderBuffers[BASIC_SHADER_TYPE_COLOR], 0, NULL, &shaderData, 0, 0 );
	
	//attach the shaders
	dContext.VSSetShader(&basicVShaders[BASIC_SHADER_TYPE_COLOR], NULL, 0 );
	dContext.HSSetShader(NULL, NULL, 0 );
	dContext.DSSetShader(NULL, NULL, 0 );
	dContext.GSSetShader(NULL, NULL, 0 );
	dContext.PSSetShader(&basicPShaders[BASIC_SHADER_TYPE_COLOR], NULL, 0 );
	
	//called after all the shaders are set before drawing (for opengl shader object) compatibility
	dContext.shaderBegin();

		//vertex
		dContext.VSSetConstantBuffers(0, 1, &shaderBuffers[BASIC_SHADER_TYPE_COLOR], basicCSVariable.shaderBufferIndex);
	
		//pixel
		dContext.PSSetConstantBuffers(0, 1, &shaderBuffers[BASIC_SHADER_TYPE_COLOR], basicCSVariable.shaderBufferIndex);
			
		//Set the input layout
		dContext.setInputLayout(&vertexLayouts[BASIC_SHADER_TYPE_COLOR]);
		//set vertex buffer
		dContext.setVertexBuffers(0,1,&vertexBuffer,sizeof(vertexP),0);
		// Set primitive topology
		dContext.setPrimitiveTopology(topology);
		//draw the non indexed primitive
		dContext.draw(vertexCount, startVertexLocation);

	dContext.shaderEnd();

	return true;
}
//uses basic shader to draw
bool graphicsUtility::drawColor(deviceContext &dContext,buffer &vertexBuffer, buffer &indexBuffer,const graphicsDefinitions::PRIMITIVE_TOPOLOGY &topology,const float4x4 &worldMatrix,const float4x4 &viewMatrix, const float4x4 &projMatrix,const float4 &color,const unsigned int &indexCount,const unsigned int &startIndexLocation,const int &baseVertexLocation)
{	
	// Update variables that change once per frame
	struct shaderBufferColor shaderData;
	shaderData.worldMatrix=worldMatrix;
	shaderData.viewMatrix=viewMatrix; 
	shaderData.projMatrix=projMatrix;
	shaderData.color=color;
	
	dContext.updateSubResource(&shaderBuffers[BASIC_SHADER_TYPE_COLOR], 0, NULL, &shaderData, 0, 0 );

	//attach the shaders
	dContext.VSSetShader(&basicVShaders[BASIC_SHADER_TYPE_COLOR], NULL, 0 );
	dContext.HSSetShader(NULL, NULL, 0 );
	dContext.DSSetShader(NULL, NULL, 0 );
	dContext.GSSetShader(NULL, NULL, 0 );
	dContext.PSSetShader(&basicPShaders[BASIC_SHADER_TYPE_COLOR], NULL, 0 );
	
	//called after all the shaders are set before drawing (for opengl shader object) compatibility
	dContext.shaderBegin();

		//vertex
		dContext.VSSetConstantBuffers(0, 1, &shaderBuffers[BASIC_SHADER_TYPE_COLOR], basicCSVariable.shaderBufferIndex);
	
		//pixel
		dContext.PSSetConstantBuffers(0, 1, &shaderBuffers[BASIC_SHADER_TYPE_COLOR], basicCSVariable.shaderBufferIndex);


		//Set the input layout
		dContext.setInputLayout(&vertexLayouts[BASIC_SHADER_TYPE_COLOR]);
		//set vertex buffer
		dContext.setVertexBuffers(0,1,&vertexBuffer,sizeof(vertexP),0);
		//set index buffer
		dContext.setIndexBuffer(&indexBuffer,graphicsDefinitions::DATA_FORMAT_R16_UINT,0);
		//// Set primitive topology
		dContext.setPrimitiveTopology(topology);
		//draw the non indexed primitive
		dContext.drawIndexed(indexCount, startIndexLocation, baseVertexLocation);

	dContext.shaderEnd();

	return true;
}


//uses basic shader to draw
bool graphicsUtility::drawColorNormal(deviceContext &dContext,buffer &vertexBuffer,const graphicsDefinitions::PRIMITIVE_TOPOLOGY &topology,const float4x4 &worldMatrix,const float4x4 &viewMatrix, const float4x4 &projMatrix,const float4 &color,const light &lightData,const unsigned int &vertexCount,const unsigned int &startVertexLocation)
{

	// Update variables that change once per frame
	struct shaderBufferColorNormal shaderData;
	shaderData.worldMatrix=worldMatrix;
	shaderData.viewMatrix=viewMatrix; 
	shaderData.projMatrix=projMatrix;
	shaderData.color=color;
	shaderData.lightData=lightData;
	
	dContext.updateSubResource(&shaderBuffers[BASIC_SHADER_TYPE_COLOR_NORMAL], 0, NULL, &shaderData, 0, 0 );
	
	//attach the shaders
	dContext.VSSetShader(&basicVShaders[BASIC_SHADER_TYPE_COLOR_NORMAL], NULL, 0 );
	dContext.HSSetShader(NULL, NULL, 0 );
	dContext.DSSetShader(NULL, NULL, 0 );
	dContext.GSSetShader(NULL, NULL, 0 );
	dContext.PSSetShader(&basicPShaders[BASIC_SHADER_TYPE_COLOR_NORMAL], NULL, 0 );
	
	//called after all the shaders are set before drawing (for opengl shader object) compatibility
	dContext.shaderBegin();

		//vertex
		dContext.VSSetConstantBuffers(0, 1, &shaderBuffers[BASIC_SHADER_TYPE_COLOR_NORMAL], basicCNSVariable.shaderBufferIndex);
	
		//pixel
		dContext.PSSetConstantBuffers(0, 1, &shaderBuffers[BASIC_SHADER_TYPE_COLOR_NORMAL], basicCNSVariable.shaderBufferIndex);

		//Set the input layout
		dContext.setInputLayout(&vertexLayouts[BASIC_SHADER_TYPE_COLOR_NORMAL]);
		//set vertex buffer
		dContext.setVertexBuffers(0,1,&vertexBuffer,sizeof(vertexPN),0);
		// Set primitive topology
		dContext.setPrimitiveTopology(topology);
		//draw the non indexed primitive
		dContext.draw(vertexCount, startVertexLocation);

	dContext.shaderEnd();

	return true;
}
//uses basic shader to draw
bool graphicsUtility::drawColorNormal(deviceContext &dContext,buffer &vertexBuffer, buffer &indexBuffer,const graphicsDefinitions::PRIMITIVE_TOPOLOGY &topology,const float4x4 &worldMatrix,const float4x4 &viewMatrix, const float4x4 &projMatrix,const float4 &color,const light &lightData,const unsigned int &indexCount,const unsigned int &startIndexLocation,const int &baseVertexLocation)
{	
	// Update variables that change once per frame
	struct shaderBufferColorNormal shaderData;
	shaderData.worldMatrix=worldMatrix;
	shaderData.viewMatrix=viewMatrix; 
	shaderData.projMatrix=projMatrix;
	shaderData.color=color;
	shaderData.lightData=lightData;
	
	dContext.updateSubResource(&shaderBuffers[BASIC_SHADER_TYPE_COLOR_NORMAL], 0, NULL, &shaderData, 0, 0 );

	//attach the shaders
	dContext.VSSetShader(&basicVShaders[BASIC_SHADER_TYPE_COLOR_NORMAL], NULL, 0 );
	dContext.HSSetShader(NULL, NULL, 0 );
	dContext.DSSetShader(NULL, NULL, 0 );
	dContext.GSSetShader(NULL, NULL, 0 );
	dContext.PSSetShader(&basicPShaders[BASIC_SHADER_TYPE_COLOR_NORMAL], NULL, 0 );
	
	//called after all the shaders are set before drawing (for opengl shader object) compatibility
	dContext.shaderBegin();

		//vertex
		dContext.VSSetConstantBuffers(0, 1, &shaderBuffers[BASIC_SHADER_TYPE_COLOR_NORMAL], basicCNSVariable.shaderBufferIndex);
	
		//pixel
		dContext.PSSetConstantBuffers(0, 1, &shaderBuffers[BASIC_SHADER_TYPE_COLOR_NORMAL], basicCNSVariable.shaderBufferIndex);


		//Set the input layout
		dContext.setInputLayout(&vertexLayouts[BASIC_SHADER_TYPE_COLOR_NORMAL]);
		//set vertex buffer
		dContext.setVertexBuffers(0,1,&vertexBuffer,sizeof(vertexPN),0);
		//set index buffer
		dContext.setIndexBuffer(&indexBuffer,graphicsDefinitions::DATA_FORMAT_R16_UINT,0);
		//// Set primitive topology
		dContext.setPrimitiveTopology(topology);
		//draw the non indexed primitive
		dContext.drawIndexed(indexCount, startIndexLocation, baseVertexLocation);

	dContext.shaderEnd();

	return true;
}


//uses basic shader to draw
bool graphicsUtility::drawColorTexture(deviceContext &dContext,buffer &vertexBuffer,shaderResourceView &textureSRV,samplerState &textureSampler,const graphicsDefinitions::PRIMITIVE_TOPOLOGY &topology,const float4x4 &worldMatrix,const float4x4 &viewMatrix, const float4x4 &projMatrix,const float4 &color,const unsigned int &vertexCount,const unsigned int &startVertexLocation)
{

	// Update variables that change once per frame
	struct shaderBufferColor shaderData;
	shaderData.worldMatrix=worldMatrix;
	shaderData.viewMatrix=viewMatrix; 
	shaderData.projMatrix=projMatrix;
	shaderData.color=color;
	
	dContext.updateSubResource(&shaderBuffers[BASIC_SHADER_TYPE_COLOR_TEXTURE], 0, NULL, &shaderData, 0, 0 );
	
	//attach the shaders
	dContext.VSSetShader(&basicVShaders[BASIC_SHADER_TYPE_COLOR_TEXTURE], NULL, 0 );
	dContext.HSSetShader(NULL, NULL, 0 );
	dContext.DSSetShader(NULL, NULL, 0 );
	dContext.GSSetShader(NULL, NULL, 0 );
	dContext.PSSetShader(&basicPShaders[BASIC_SHADER_TYPE_COLOR_TEXTURE], NULL, 0 );
	
	//called after all the shaders are set before drawing (for opengl shader object) compatibility
	dContext.shaderBegin();

		//vertex
		dContext.VSSetConstantBuffers(0, 1, &shaderBuffers[BASIC_SHADER_TYPE_COLOR_TEXTURE], basicCTSVariable.shaderBufferIndex);
	
		//pixel
		dContext.PSSetConstantBuffers(0, 1, &shaderBuffers[BASIC_SHADER_TYPE_COLOR_TEXTURE], basicCTSVariable.shaderBufferIndex);
		dContext.PSSetShaderResources(0, 1, &textureSRV,basicCTSVariable.textureIndex);
		dContext.PSSetSamplers(0, 1, &textureSampler);

	
		//Set the input layout
		dContext.setInputLayout(&vertexLayouts[BASIC_SHADER_TYPE_COLOR_TEXTURE]);
		//set vertex buffer
		dContext.setVertexBuffers(0,1,&vertexBuffer,sizeof(vertexPT),0);
		// Set primitive topology
		dContext.setPrimitiveTopology(topology);
		//draw the non indexed primitive
		dContext.draw(vertexCount, startVertexLocation);

	dContext.shaderEnd();

	return true;
}
//uses basic shader to draw
bool graphicsUtility::drawColorTexture(deviceContext &dContext,buffer &vertexBuffer, buffer &indexBuffer,shaderResourceView &textureSRV,samplerState &textureSampler,const graphicsDefinitions::PRIMITIVE_TOPOLOGY &topology,const float4x4 &worldMatrix,const float4x4 &viewMatrix, const float4x4 &projMatrix,const float4 &color,const unsigned int &indexCount,const unsigned int &startIndexLocation,const int &baseVertexLocation)
{	
	// Update variables that change once per frame
	struct shaderBufferColor shaderData;
	shaderData.worldMatrix=worldMatrix;
	shaderData.viewMatrix=viewMatrix; 
	shaderData.projMatrix=projMatrix;
	shaderData.color=color;

	dContext.updateSubResource(&shaderBuffers[BASIC_SHADER_TYPE_COLOR_TEXTURE], 0, NULL, &shaderData, 0, 0 );
	
	//attach the shaders
	dContext.VSSetShader(&basicVShaders[BASIC_SHADER_TYPE_COLOR_TEXTURE], NULL, 0 );
	dContext.HSSetShader(NULL, NULL, 0 );
	dContext.DSSetShader(NULL, NULL, 0 );
	dContext.GSSetShader(NULL, NULL, 0 );
	dContext.PSSetShader(&basicPShaders[BASIC_SHADER_TYPE_COLOR_TEXTURE], NULL, 0 );
	
	//called after all the shaders are set before drawing (for opengl shader object) compatibility
	dContext.shaderBegin();

		//vertex
		dContext.VSSetConstantBuffers(0, 1, &shaderBuffers[BASIC_SHADER_TYPE_COLOR_TEXTURE], basicCTSVariable.shaderBufferIndex);
	
		//pixel
		dContext.PSSetConstantBuffers(0, 1, &shaderBuffers[BASIC_SHADER_TYPE_COLOR_TEXTURE], basicCTSVariable.shaderBufferIndex);
		dContext.PSSetShaderResources(0, 1, &textureSRV,basicCTSVariable.textureIndex);
		dContext.PSSetSamplers(0, 1, &textureSampler);
	

		//Set the input layout
		dContext.setInputLayout(&vertexLayouts[BASIC_SHADER_TYPE_COLOR_TEXTURE]);
		//set vertex buffer
		dContext.setVertexBuffers(0,1,&vertexBuffer,sizeof(vertexPT),0);
		//set index buffer
		dContext.setIndexBuffer(&indexBuffer,graphicsDefinitions::DATA_FORMAT_R16_UINT,0);
		//// Set primitive topology
		dContext.setPrimitiveTopology(topology);
		//draw the non indexed primitive
		dContext.drawIndexed(indexCount, startIndexLocation, baseVertexLocation);

	dContext.shaderEnd();
	return true;
}


//uses basic shader to draw
bool graphicsUtility::drawColorTexture2D(deviceContext &dContext,buffer &vertexBuffer,shaderResourceView &textureSRV,samplerState &textureSampler,const graphicsDefinitions::PRIMITIVE_TOPOLOGY &topology,const float4 &color,const unsigned int &vertexCount,const unsigned int &startVertexLocation)
{

	// Update variables that change once per frame
	struct shaderBufferColor2D shaderData;
	shaderData.dimension=float4((float)gl.getWidth(),(float)gl.getHeight(),0,0);
	shaderData.color=color;
	
	dContext.updateSubResource(&shaderBuffers[BASIC_SHADER_TYPE_TEXTURE_2D], 0, NULL, &shaderData, 0, 0 );
	
	//attach the shaders
	dContext.VSSetShader(&basicVShaders[BASIC_SHADER_TYPE_TEXTURE_2D], NULL, 0 );
	dContext.HSSetShader(NULL, NULL, 0 );
	dContext.DSSetShader(NULL, NULL, 0 );
	dContext.GSSetShader(NULL, NULL, 0 );
	dContext.PSSetShader(&basicPShaders[BASIC_SHADER_TYPE_TEXTURE_2D], NULL, 0 );
	
	//called after all the shaders are set before drawing (for opengl shader object) compatibility
	dContext.shaderBegin();

		//vertex
		dContext.VSSetConstantBuffers(0, 1, &shaderBuffers[BASIC_SHADER_TYPE_TEXTURE_2D], basicCT2DSVariable.shaderBufferIndex);
	
		//pixel
		dContext.PSSetConstantBuffers(0, 1, &shaderBuffers[BASIC_SHADER_TYPE_TEXTURE_2D], basicCT2DSVariable.shaderBufferIndex);
		dContext.PSSetShaderResources(0, 1, &textureSRV,basicCT2DSVariable.textureIndex);
		dContext.PSSetSamplers(0, 1, &textureSampler);

	
		//Set the input layout
		dContext.setInputLayout(&vertexLayouts[BASIC_SHADER_TYPE_TEXTURE_2D]);
		//set vertex buffer
		dContext.setVertexBuffers(0,1,&vertexBuffer,sizeof(vertexPT),0);
		// Set primitive topology
		dContext.setPrimitiveTopology(topology);
		//draw the non indexed primitive
		dContext.draw(vertexCount, startVertexLocation);

	dContext.shaderEnd();

	return true;
}



//uses basic shader to draw
bool graphicsUtility::drawColorNormalTexture(deviceContext &dContext,buffer &vertexBuffer,shaderResourceView &textureSRV,samplerState &textureSampler,const graphicsDefinitions::PRIMITIVE_TOPOLOGY &topology,const float4x4 &worldMatrix,const float4x4 &viewMatrix, const float4x4 &projMatrix,const float4 &color,const light &lightData,const unsigned int &vertexCount,const unsigned int &startVertexLocation)
{

	// Update variables that change once per frame
	struct shaderBufferColorNormal shaderData;
	shaderData.worldMatrix=worldMatrix;
	shaderData.viewMatrix=viewMatrix; 
	shaderData.projMatrix=projMatrix;
	shaderData.color=color;
	shaderData.lightData=lightData;
	
	dContext.updateSubResource(&shaderBuffers[BASIC_SHADER_TYPE_COLOR_NORMAL_TEXTURE], 0, NULL, &shaderData, 0, 0 );
	
	//attach the shaders
	dContext.VSSetShader(&basicVShaders[BASIC_SHADER_TYPE_COLOR_NORMAL_TEXTURE], NULL, 0 );
	dContext.HSSetShader(NULL, NULL, 0 );
	dContext.DSSetShader(NULL, NULL, 0 );
	dContext.GSSetShader(NULL, NULL, 0 );
	dContext.PSSetShader(&basicPShaders[BASIC_SHADER_TYPE_COLOR_NORMAL_TEXTURE], NULL, 0 );
	
	//called after all the shaders are set before drawing (for opengl shader object) compatibility
	dContext.shaderBegin();

		//vertex
		dContext.VSSetConstantBuffers(0, 1, &shaderBuffers[BASIC_SHADER_TYPE_COLOR_NORMAL_TEXTURE], basicCNTSVariable.shaderBufferIndex);
	
		//pixel
		dContext.PSSetConstantBuffers(0, 1, &shaderBuffers[BASIC_SHADER_TYPE_COLOR_NORMAL_TEXTURE], basicCNTSVariable.shaderBufferIndex);
		dContext.PSSetShaderResources(0, 1, &textureSRV,basicCNTSVariable.textureIndex);
		dContext.PSSetSamplers(0, 1, &textureSampler);
		
		//Set the input layout
		dContext.setInputLayout(&vertexLayouts[BASIC_SHADER_TYPE_COLOR_NORMAL_TEXTURE]);
		//set vertex buffer
		dContext.setVertexBuffers(0,1,&vertexBuffer,sizeof(vertexPNT),0);
		// Set primitive topology
		dContext.setPrimitiveTopology(topology);
		//draw the non indexed primitive
		dContext.draw(vertexCount, startVertexLocation);

	dContext.shaderEnd();

	return true;
}
//uses basic shader to draw
bool graphicsUtility::drawColorNormalTexture(deviceContext &dContext,buffer &vertexBuffer, buffer &indexBuffer,shaderResourceView &textureSRV,samplerState &textureSampler,const graphicsDefinitions::PRIMITIVE_TOPOLOGY &topology,const float4x4 &worldMatrix,const float4x4 &viewMatrix, const float4x4 &projMatrix,const float4 &color,const light &lightData,const unsigned int &indexCount,const unsigned int &startIndexLocation,const int &baseVertexLocation)
{	
	// Update variables that change once per frame
	struct shaderBufferColorNormal shaderData;
	shaderData.worldMatrix=worldMatrix;
	shaderData.viewMatrix=viewMatrix; 
	shaderData.projMatrix=projMatrix;
	shaderData.color=color;
	shaderData.lightData=lightData;
	
	dContext.updateSubResource(&shaderBuffers[BASIC_SHADER_TYPE_COLOR_NORMAL_TEXTURE], 0, NULL, &shaderData, 0, 0 );
	
	//attach the shaders
	dContext.VSSetShader(&basicVShaders[BASIC_SHADER_TYPE_COLOR_NORMAL_TEXTURE], NULL, 0 );
	dContext.HSSetShader(NULL, NULL, 0 );
	dContext.DSSetShader(NULL, NULL, 0 );
	dContext.GSSetShader(NULL, NULL, 0 );
	dContext.PSSetShader(&basicPShaders[BASIC_SHADER_TYPE_COLOR_NORMAL_TEXTURE], NULL, 0 );
	
	//called after all the shaders are set before drawing (for opengl shader object) compatibility
	dContext.shaderBegin();

		//vertex
		dContext.VSSetConstantBuffers(0, 1, &shaderBuffers[BASIC_SHADER_TYPE_COLOR_NORMAL_TEXTURE], basicCNTSVariable.shaderBufferIndex);
	
		//pixel
		dContext.PSSetConstantBuffers(0, 1, &shaderBuffers[BASIC_SHADER_TYPE_COLOR_NORMAL_TEXTURE], basicCNTSVariable.shaderBufferIndex);
		dContext.PSSetShaderResources(0, 1, &textureSRV,basicCTSVariable.textureIndex);
		dContext.PSSetSamplers(0, 1, &textureSampler);


		//Set the input layout
		dContext.setInputLayout(&vertexLayouts[BASIC_SHADER_TYPE_COLOR_NORMAL_TEXTURE]);
		//set vertex buffer
		dContext.setVertexBuffers(0,1,&vertexBuffer,sizeof(vertexPNT),0);
		//set index buffer
		dContext.setIndexBuffer(&indexBuffer,graphicsDefinitions::DATA_FORMAT_R16_UINT,0);
		//// Set primitive topology
		dContext.setPrimitiveTopology(topology);
		//draw the non indexed primitive
		dContext.drawIndexed(indexCount, startIndexLocation, baseVertexLocation);

	dContext.shaderEnd();

	return true;
}

//prints text in the screen
void graphicsUtility::print(deviceContext &dContext, const float2 &position,const char *string, ...)
{
	//check if the string is null
    if (string == NULL)                                
        return;

	char *strText;	//final string
    int strLen;     //final string length
    va_list argumentPtr;    //argument list

    // Parse the arguments out of the string
    va_start(argumentPtr, string);

    //get the string length
    strLen= _vscprintf(string, argumentPtr);

    //allocate the array
    strText=new char[strLen+1];

    //convert argument list into string
    vsprintf(strText, string, argumentPtr);            

    // This resets and frees the pointer to the argument list.
    va_end(argumentPtr);

	float2 currPos=position;		
	font &currFont=fonts[BASIC_FONT_TYPE_ASCII];
	
	//length of string
	unsigned int length=(int)strlen(strText);

	bucketList<graphicsUtility::vertexPT> vertexData(40);
	

	for(unsigned int i=0;i<length;++i)
	{
		unsigned int asciiValue=(unsigned int)(strText[i]);

		font::charInfo &currChar=currFont.charDetails[asciiValue];
				
		//compute position of the character
		float x=float(asciiValue%currFont.charPerRow)/currFont.charPerRow;
		float y=float(asciiValue/currFont.charPerRow)/currFont.charPerCol;

		const unsigned &charWidth=currChar.width;
		const unsigned &charHeight=currChar.height;

		float relativeSizeX=charWidth/(float)currFont.imageWidth;
		float relativeSizeY=charHeight/(float)currFont.imageHeight;

		vertexData.addBack(vertexPT( float3( currPos.x+0.0f,      currPos.y+0.0f,        0.0f ), float2(x,(y+relativeSizeY))));
		vertexData.addBack(vertexPT( float3( currPos.x+charWidth, currPos.y+0.0f,        0.0f ), float2(x+relativeSizeX,(y+relativeSizeY)) ));
		vertexData.addBack(vertexPT( float3( currPos.x+0.0f ,     currPos.y+charHeight,  0.0f ), float2(x,y) ));

		vertexData.addBack(vertexPT( float3( currPos.x+0.0f ,     currPos.y+charHeight,  0.0f ), float2(x,y) ));
		vertexData.addBack(vertexPT( float3( currPos.x+charWidth, currPos.y+0.0f,        0.0f ), float2(x+relativeSizeX,(y+relativeSizeY)) ));
		vertexData.addBack(vertexPT( float3( currPos.x+charWidth, currPos.y+charHeight,  0.0f ), float2(x+relativeSizeX,y) ));
			
		//translate value
		currPos.x+=currChar.translateAmount;
	}
    delete[] strText;

	//uses basic shader to draw
	drawColorTexture2D(dContext,vertexData,currFont.fontTextureSRV,currFont.fontTextureSampler,graphicsDefinitions::PRIMITIVE_TOPOLOGY_TRIANGLELIST,currFont.color);
}

//draws the grid
void graphicsUtility::showGrid(const camera &eye)
{
	//save the height
	float height=(eye.getPosition().y);

	//number of layout count
	int level=0;

	//blend value for different colors
	float blendValue=1.0f;

	//create local camera
	camera localCam=eye;
	//look down
	localCam.setAxis(float3(0.0f,-1.0f,0.0f),float3(0.0f,0.0f,1.0f),float3(1.0f,0.0f,0.0f));
	localCam.setPosition(float3(0,height,0));
	//recompute modelview matrix
	localCam.computeViewMatrixLH();

	for(int i=-10;i<100;i++)
	{
		float3 pos0=localCam.worldToScreen(float3(0,0,0));
		float3 pos1=localCam.worldToScreen(float3(pow(10.0f,(float)i),0,pow(10.0f,(float)i)));
		//clear the depth component
		pos0.z=0;
		pos1.z=0;
		//get distance
		float distance=length(pos0-pos1);

		//distance is greater than k pixels then continue
		if(distance>40)
		{
			//blend value for different colors
			blendValue=MIN((distance-20)/4.0f,1.0f);
			//set the level
			level=i;

			break;
		}
	}

	float3 blendColor(.90f,0.90f,0.95f);
	float3 fineLineColor(.7f,.7f,.7f);
	float3 boldLineColor(.3f,.3f,.3f);
	
	bucketList<graphicsUtility::vertexPN> vertexData(256);

	//////////////////////////////////////////////////////////////////////
	//fine lines
	float3 blendedColor=blendColor*(1-blendValue)+fineLineColor*blendValue;
	float4 color(blendedColor.x,blendedColor.y,blendedColor.z,blendValue);

	//number of lines to show
	int numLines=100;//(unsigned int)(horizon/pow(10.0f,(float)level));
	float horizon=(numLines-1)*pow(10.0f,(float)level);

	float stepSize=pow(10.0f,(float)level);
	float3 gridStartPosition=eye.getPosition();

	//find the nearest grid position
	gridStartPosition.x-=fmod(gridStartPosition.x,stepSize);
	gridStartPosition.y=0;
	gridStartPosition.z-=fmod(gridStartPosition.z,stepSize);

	//find the starting position
	gridStartPosition.x-=numLines/2*stepSize;
	gridStartPosition.z-=numLines/2*stepSize;

	int addAlphaX=(int)(gridStartPosition.x/stepSize);
	int addAlphaZ=(int)(gridStartPosition.z/stepSize);
	
	for(int i=0;i<numLines;i++)
	{
		//vertical lines
		if((i+addAlphaX)%10!=0)
		{
			vertexData.addBack(graphicsUtility::vertexPN(float3(gridStartPosition.x+i*stepSize,0,gridStartPosition.z+horizon),float3(  0.0f,  1.0f,  0.0f)));//float2(horizon,horizon)));
			vertexData.addBack(graphicsUtility::vertexPN(float3(gridStartPosition.x+i*stepSize,0,gridStartPosition.z),float3(  0.0f,  1.0f,  0.0f)));//,float2(-horizon,-horizon)));
		}

		//horizontal lines
		if((i+addAlphaZ)%10!=0)
		{
			vertexData.addBack(graphicsUtility::vertexPN(float3(gridStartPosition.x+horizon,0.0f,gridStartPosition.z+i*stepSize),float3(  0.0f,  1.0f,  0.0f)));//,float2(horizon,horizon)));
			vertexData.addBack(graphicsUtility::vertexPN(float3(gridStartPosition.x,0.0f,gridStartPosition.z+i*stepSize),float3(  0.0f,  1.0f,  0.0f)));//,float2(-horizon,-horizon)));
		}
	}


	float4x4 worldMatrix;
	worldMatrix.identity();

	graphicsUtility::light lightData;
	memset(&lightData,0,sizeof(graphicsUtility::light));
	lightData.position=float3(10,10,0);
	lightData.direction=normalize(float3(0,0,0)-lightData.position);
	lightData.color=float3(1,1,1);
		
	//draw 
	drawColorNormal(getDeviceContext(),vertexData,graphicsDefinitions::PRIMITIVE_TOPOLOGY_LINELIST,worldMatrix,eye.getViewMatrix(),eye.getProjectionMatrix(),color,lightData);

	vertexData.clear();
	////////////////////////////////////////////////////////////////////////

	//////////////////////////////////////////////////////////////////////////
	//bold lines
	blendedColor=fineLineColor*(1-blendValue)+boldLineColor*blendValue;
	color=float4(blendedColor.x,blendedColor.y,blendedColor.z,1.0f);
	//bold lines
	for(int i=0;i<numLines;i++)
	{
		//vertical lines
		if((i+addAlphaX)%10==0)
		{
			vertexData.addBack(graphicsUtility::vertexPN(float3(gridStartPosition.x+i*stepSize,0,gridStartPosition.z+horizon),float3(  0.0f,  1.0f,  0.0f)));//float2(horizon,horizon)));
			vertexData.addBack(graphicsUtility::vertexPN(float3(gridStartPosition.x+i*stepSize,0,gridStartPosition.z),float3(  0.0f,  1.0f,  0.0f)));//,float2(-horizon,-horizon)));
		}

		//horizontal lines
		if((i+addAlphaZ)%10==0)
		{
			vertexData.addBack(graphicsUtility::vertexPN(float3(gridStartPosition.x+horizon,0.0f,gridStartPosition.z+i*stepSize),float3(  0.0f,  1.0f,  0.0f)));//,float2(horizon,horizon)));
			vertexData.addBack(graphicsUtility::vertexPN(float3(gridStartPosition.x,0.0f,gridStartPosition.z+i*stepSize),float3(  0.0f,  1.0f,  0.0f)));//,float2(-horizon,-horizon)));
		}
	}

	//draw 
	drawColorNormal(getDeviceContext(),vertexData,graphicsDefinitions::PRIMITIVE_TOPOLOGY_LINELIST,worldMatrix,eye.getViewMatrix(),eye.getProjectionMatrix(),color,lightData);

	////////////////////////////////////////////////////////////////////
}

//enables wireframe
void graphicsUtility::setWireFrame(bool enabled)
{
	if(enabled)
		dContext.RSSetState(&wireFrameStateMode); //set wireframe
	else
		dContext.RSSetState(&solidStateMode); //set the mode to fill
				
}

//frees the memory
void graphicsUtility::clear(void)
{

	//shader that just colors
	delete[] basicVShaders;
	delete[] basicPShaders;
	basicVShaders=NULL;
	basicPShaders=NULL;	

	//vertex layouts
	delete[] vertexLayouts;
	vertexLayouts=NULL;

	//shader buffers
	delete[] shaderBuffers;
	shaderBuffers=NULL;

	//fonts
	delete[] fonts;
	fonts=NULL;
}

//destructor
graphicsUtility::~graphicsUtility()
{
	//frees the memory
	clear();
}